package com.sas.controller;

import com.sas.common.Result;
import com.sas.entity.Customer;
import com.sas.dto.CustomerView;
import com.sas.repository.CustomerRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Map;

/**
 * 客户管理Controller
 */
@RestController
@RequestMapping("/customers")
@Validated
public class CustomerController {

    private static final Logger log = LoggerFactory.getLogger(CustomerController.class);

    @Autowired
    private CustomerRepository customerRepository;

    /**
     * 客户列表（分页 + 可选筛选）
     */
    @GetMapping
    public Result<Object> getCustomers(
            @RequestParam(defaultValue = "0") Integer page,
            @RequestParam(defaultValue = "10") Integer size,
            @RequestParam(required = false) String name,
            @RequestParam(required = false) String status,
            @RequestParam(required = false, name = "careLevel") String careLevel,
            @RequestParam(required = false) String gender
    ) {
        log.info("查询客户列表 page={}, size={}, name={}, status={}, careLevel={}, gender={}", page, size, name, status, careLevel, gender);
        try {
            PageRequest pageable = PageRequest.of(page, size);

            // 优先使用分页查询；有筛选时使用对应仓储方法或内存过滤后分页封装
            List<Customer> list;
            if (name != null && !name.trim().isEmpty()) {
                list = customerRepository.findByNameContaining(name.trim());
            } else if (status != null && !status.trim().isEmpty()) {
                Integer st = parseStatus(status);
                list = st == null ? new ArrayList<>() : customerRepository.findByStatus(st);
            } else if (careLevel != null && !careLevel.trim().isEmpty()) {
                Integer cl = parseCareLevel(careLevel);
                list = cl == null ? new ArrayList<>() : customerRepository.findByCareLevel(cl);
            } else if (gender != null && !gender.trim().isEmpty()) {
                Integer g = parseGender(gender);
                if (g == null) {
                    list = new ArrayList<>();
                } else {
                    // 默认只展示活跃客户
                    list = customerRepository.findByGenderAndStatus(g, 1);
                }
            } else {
                Page<Customer> pageData = customerRepository.findAll(pageable);
                // 转换为视图对象
                List<CustomerView> views = new ArrayList<>();
                for (Customer c : pageData.getContent()) {
                    views.add(toView(c));
                }
                // 包装为前端期望的结构：{ data: { content, totalElements } }
                java.util.Map<String, Object> pagePayload = new java.util.HashMap<>();
                pagePayload.put("content", views);
                pagePayload.put("totalElements", pageData.getTotalElements());
                java.util.Map<String, Object> wrapper = new java.util.HashMap<>();
                wrapper.put("data", pagePayload);
                return Result.success(wrapper);
            }

            // 将列表封装为分页结构
            int start = (int) pageable.getOffset();
            int end = Math.min(start + pageable.getPageSize(), list.size());
            List<Customer> subList = start <= end ? list.subList(Math.min(start, list.size()), end) : new ArrayList<>();
            List<CustomerView> views = new ArrayList<>();
            for (Customer c : subList) {
                views.add(toView(c));
            }
            java.util.Map<String, Object> pagePayload = new java.util.HashMap<>();
            pagePayload.put("content", views);
            pagePayload.put("totalElements", list.size());
            java.util.Map<String, Object> wrapper = new java.util.HashMap<>();
            wrapper.put("data", pagePayload);
            return Result.success(wrapper);
        } catch (Exception e) {
            log.error("查询客户列表失败", e);
            return Result.error("查询客户列表失败: " + e.getMessage());
        }
    }

    /**
     * 根据ID查询客户
     */
    @GetMapping("/{id}")
    public Result<CustomerView> getCustomerById(@PathVariable Long id) {
        log.info("查询客户，ID: {}", id);
        Optional<Customer> customer = customerRepository.findById(id);
        return customer.map(c -> Result.success(toView(c))).orElseGet(() -> Result.notFound("客户不存在"));
    }

    /**
     * 根据状态查询客户
     */
    @GetMapping("/status/{status}")
    public Result<List<CustomerView>> getCustomersByStatus(@PathVariable String status) {
        log.info("根据状态查询客户: {}", status);
        Integer st = parseStatus(status);
        if (st == null) return Result.success(new ArrayList<>());
        try {
            List<CustomerView> views = new ArrayList<>();
            for (Customer c : customerRepository.findByStatus(st)) {
                views.add(toView(c));
            }
            return Result.success(views);
        } catch (Exception e) {
            log.error("根据状态查询客户失败", e);
            return Result.error("查询失败: " + e.getMessage());
        }
    }

    /**
     * 根据护理等级查询客户
     */
    @GetMapping("/care-level/{careLevel}")
    public Result<List<CustomerView>> getCustomersByCareLevel(@PathVariable String careLevel) {
        log.info("根据护理等级查询客户: {}", careLevel);
        Integer cl = parseCareLevel(careLevel);
        if (cl == null) return Result.success(new ArrayList<>());
        try {
            List<CustomerView> views = new ArrayList<>();
            for (Customer c : customerRepository.findByCareLevel(cl)) {
                views.add(toView(c));
            }
            return Result.success(views);
        } catch (Exception e) {
            log.error("根据护理等级查询客户失败", e);
            return Result.error("查询失败: " + e.getMessage());
        }
    }

    /**
     * 模糊查询客户姓名
     */
    @GetMapping("/search")
    public Result<List<CustomerView>> searchCustomers(@RequestParam String name) {
        log.info("模糊查询客户姓名: {}", name);
        try {
            List<CustomerView> views = new ArrayList<>();
            for (Customer c : customerRepository.findByNameContaining(name.trim())) {
                views.add(toView(c));
            }
            return Result.success(views);
        } catch (Exception e) {
            log.error("模糊查询客户失败", e);
            return Result.error("查询失败: " + e.getMessage());
        }
    }

    /**
     * 年龄范围查询
     */
    @GetMapping("/age-range")
    public Result<List<CustomerView>> getCustomersByAgeRange(@RequestParam Integer minAge, @RequestParam Integer maxAge) {
        log.info("按年龄范围查询客户: {}-{}", minAge, maxAge);
        try {
            List<CustomerView> views = new ArrayList<>();
            for (Customer c : customerRepository.findByAgeRange(minAge, maxAge)) {
                views.add(toView(c));
            }
            return Result.success(views);
        } catch (Exception e) {
            log.error("按年龄范围查询客户失败", e);
            return Result.error("查询失败: " + e.getMessage());
        }
    }

    /**
     * 根据性别查询（默认仅活跃客户）
     */
    @GetMapping("/gender/{gender}")
    public Result<List<CustomerView>> getCustomersByGender(@PathVariable String gender) {
        log.info("根据性别查询客户: {}", gender);
        Integer g = parseGender(gender);
        if (g == null) return Result.success(new ArrayList<>());
        try {
            List<CustomerView> views = new ArrayList<>();
            for (Customer c : customerRepository.findByGenderAndStatus(g, 1)) {
                views.add(toView(c));
            }
            return Result.success(views);
        } catch (Exception e) {
            log.error("根据性别查询客户失败", e);
            return Result.error("查询失败: " + e.getMessage());
        }
    }

    /**
     * 活跃客户按护理等级与年龄排序
     */
    @GetMapping("/active")
    public Result<List<CustomerView>> getActiveCustomers() {
        log.info("查询活跃客户按护理等级排序");
        try {
            List<CustomerView> views = new ArrayList<>();
            for (Customer c : customerRepository.findActiveCustomersOrderByCareLevelAndAge()) {
                views.add(toView(c));
            }
            return Result.success(views);
        } catch (Exception e) {
            log.error("查询活跃客户失败", e);
            return Result.error("查询失败: " + e.getMessage());
        }
    }

    /**
     * 创建客户
     */
    @PostMapping
    public Result<CustomerView> createCustomer(@RequestBody Map<String, Object> body) {
        try {
            Customer c = new Customer();
            applyRequestBodyToCustomer(body, c);
            if (c.getName() == null || c.getName().trim().isEmpty()) {
                return Result.error("客户姓名不能为空");
            }
            Customer saved = customerRepository.save(c);
            return Result.success(toView(saved));
        } catch (Exception e) {
            log.error("创建客户失败", e);
            return Result.error("创建客户失败: " + e.getMessage());
        }
    }

    /**
     * 更新客户
     */
    @PutMapping("/{id}")
    public Result<CustomerView> updateCustomer(@PathVariable Long id, @RequestBody Map<String, Object> body) {
        try {
            Optional<Customer> existingOpt = customerRepository.findById(id);
            if (!existingOpt.isPresent()) {
                return Result.notFound("客户不存在");
            }
            Customer existing = existingOpt.get();
            applyRequestBodyToCustomer(body, existing);
            // 保留创建时间，JPA的@PreUpdate会更新修改时间
            Customer saved = customerRepository.save(existing);
            return Result.success(toView(saved));
        } catch (Exception e) {
            log.error("更新客户失败", e);
            return Result.error("更新客户失败: " + e.getMessage());
        }
    }

    // ----------------- Request body mapper -----------------
    private void applyRequestBodyToCustomer(Map<String, Object> body, Customer c) {
        // 基本字段
        c.setName(asString(body.get("name")));
        c.setPhone(asString(body.get("phone")));
        c.setEmergencyContact(asString(body.get("emergencyContact")));
        c.setEmergencyPhone(asString(body.get("emergencyPhone")));
        c.setAge(asInteger(body.get("age")));

        // 枚举/级别映射（字符串或数字均可）
        Integer gender = parseGender(asStringOrNumber(body.get("gender")));
        Integer careLevel = parseCareLevel(asStringOrNumber(body.get("careLevel")));
        Integer status = parseStatus(asStringOrNumber(body.get("status")));
        c.setGender(gender);
        c.setCareLevel(careLevel);
        c.setStatus(status);

        // 医疗信息映射
        String medicalInfo = asString(body.get("medicalInfo"));
        if (medicalInfo != null) {
            c.setMedicalCondition(medicalInfo);
        }

        // 可选字段：特殊需求/护理时段
        String specialRequirements = asString(body.get("specialRequirements"));
        if (specialRequirements != null) {
            c.setSpecialRequirements(specialRequirements);
        }
        String careTimeSlots = asString(body.get("careTimeSlots"));
        if (careTimeSlots != null) {
            c.setCareTimeSlots(careTimeSlots);
        }
    }

    private String asString(Object o) {
        return o == null ? null : String.valueOf(o).trim();
    }

    private String asStringOrNumber(Object o) {
        return o == null ? null : String.valueOf(o).trim();
    }

    private Integer asInteger(Object o) {
        if (o == null) return null;
        try {
            return Integer.valueOf(String.valueOf(o).trim());
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 删除客户
     */
    @DeleteMapping("/{id}")
    public Result<Void> deleteCustomer(@PathVariable Long id) {
        log.info("删除客户，ID: {}", id);
        try {
            customerRepository.deleteById(id);
            return Result.success(null);
        } catch (Exception e) {
            log.error("删除客户失败", e);
            return Result.error("删除客户失败: " + e.getMessage());
        }
    }

    /**
     * 批量删除客户
     */
    @DeleteMapping("/batch")
    public Result<Void> deleteCustomers(@RequestBody java.util.Map<String, List<Long>> body) {
        List<Long> ids = body != null ? body.get("ids") : null;
        log.info("批量删除客户，IDs: {}", ids);
        if (ids == null) {
            return Result.error("请求体缺少ids数组");
        }
        try {
            ids.forEach(customerRepository::deleteById);
            return Result.success(null);
        } catch (Exception e) {
            log.error("批量删除客户失败", e);
            return Result.error("批量删除客户失败: " + e.getMessage());
        }
    }

    /**
     * 简单客户统计信息
     */
    @GetMapping("/stats")
    public Result<java.util.Map<String, Object>> getCustomerStats() {
        try {
            java.util.Map<String, Object> stats = new java.util.HashMap<>();
            List<Customer> actives = customerRepository.findByStatus(1);
            List<Customer> inactives = customerRepository.findByStatus(0);
            stats.put("active", actives.size());
            stats.put("inactive", inactives.size());
            stats.put("total", actives.size() + inactives.size());
            return Result.success(stats);
        } catch (Exception e) {
            log.error("获取客户统计失败", e);
            return Result.error("获取客户统计失败: " + e.getMessage());
        }
    }

    // ----------------- Helper converters -----------------
    private Integer parseStatus(String status) {
        if (status == null) return null;
        String s = status.trim().toUpperCase();
        if (s.isEmpty()) return null;
        return "ACTIVE".equals(s) ? 1 : 0;
    }

    private Integer parseGender(String gender) {
        if (gender == null) return null;
        String g = gender.trim().toUpperCase();
        switch (g) {
            case "1":
            case "MALE":
                return 1;
            case "2":
            case "FEMALE":
                return 2;
            case "3":
            case "OTHER":
                return 3;
            default:
                return null;
        }
    }

    private Integer parseCareLevel(String careLevel) {
        if (careLevel == null) return null;
        String cl = careLevel.trim().toUpperCase();
        switch (cl) {
            case "1":
            case "LOW":
            case "LEVEL_1":
                return 1;
            case "2":
            case "MEDIUM":
            case "LEVEL_2":
                return 2;
            case "3":
            case "HIGH":
            case "LEVEL_3":
                return 3;
            case "4":
            case "INTENSIVE":
            case "SPECIAL":
                return 4;
            default:
                return null;
        }
    }

    // 将实体转换为前端视图对象（字符串枚举）
    private CustomerView toView(Customer c) {
        CustomerView v = new CustomerView();
        v.id = c.getId();
        v.name = c.getName();
        v.age = c.getAge();
        v.phone = c.getPhone();
        v.emergencyContact = c.getEmergencyContact();
        v.emergencyPhone = c.getEmergencyPhone();
        // gender
        if (c.getGender() == null) {
            v.gender = null;
        } else {
            switch (c.getGender()) {
                case 1: v.gender = "MALE"; break;
                case 2: v.gender = "FEMALE"; break;
                default: v.gender = "OTHER"; break;
            }
        }
        // care level
        if (c.getCareLevel() == null) {
            v.careLevel = null;
        } else {
            switch (c.getCareLevel()) {
                case 1: v.careLevel = "LEVEL_1"; break;
                case 2: v.careLevel = "LEVEL_2"; break;
                case 3: v.careLevel = "LEVEL_3"; break;
                case 4: v.careLevel = "SPECIAL"; break;
                default: v.careLevel = null; break;
            }
        }
        // status
        v.status = (c.getStatus() != null && c.getStatus() == 1) ? "ACTIVE" : "INACTIVE";
        // 兼容展示字段（当前实体暂未提供）
        v.roomNumber = null;
        v.admissionDate = null;
        v.medicalInfo = c.getMedicalCondition();
        return v;
    }
}